/**
 * 选取一些作为必填，而其他的选项维持原定义
 *
 * 注: 常用于某些属性是可选的，但是 sdk 内部给某些键设置了默认值的情况.
 *
 * @example
 * ```ts
 * type Test = {
 *   a?: number
 *   b: string
 *   c?: boolean
 * }
 *
 * PickForRequired<Test, 'a' | 'b'>
 * {
 *   a: number
 *   b: string
 *   c?: boolean
 * }
 * ```
 */
export type PickForRequired<T, K extends keyof T, P> = Required<Pick<T, K>> & Omit<T, K>

/**
 * 选取一些作为必填，而其他的选项均为选填
 *
 * @example
 * ```ts
 * type Test = {
 *   a?: number
 *   b: string
 *   c?: boolean
 * }
 *
 * PickForRequired<Test, 'a'>
 * {
 *   a: number
 *   b?: string
 *   c?: boolean
 * }
 * ```
 */
export type PickForRequiredAndPartialTheRest<T, K extends keyof T> = Required<Pick<T, K>> & Partial<Omit<T, K>>

/**
 * 接收一个 Promise, 并返回一个元组 [error, data]
 *
 * @param {Promise<T>} promise - 待处理的 Promise 对象
 * @returns {Promise<[Error | null, T | undefined]>} - 返回一个 Promise 对象，该对象解析为一个包含错误和数据的元组
 * @example
 * ```
 * const [error, text] = await to(fetch('https://baidu.com'))
 * if (error || !text) {
 *   // todo 处理失败逻辑
 *   console.error('fetch error', error)
 *   return
 * }
 * console.log('fetch success and get', text)
 * ```
 */
export function to<T>(promise: Promise<T>): Promise<[Error | null, T | undefined]> {
  return promise.then<[null, T]>((data: T) => [null, data]).catch<[Error, undefined]>((error: Error) => [error, undefined])
}
// JS 版本
// export function to(promise) {
//   return promise.then((data) => [null, data]).catch((error) => [error, undefined]);
// }
